// Copyright  2004-2008 Backplane Ltd.
//
// This file is part of Ubiquity formsPlayer
//
// Ubiquity formsPlayer is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3 of the License, or (at your
// option) any later version.
//
// Ubiquity formsPlayer is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
// more details.
//
// You should have received a copy of the GNU General Public License
// along with Ubiquity formsPlayer If not, see <http://www.gnu.org/licenses/>.
//	
//
//   Purpose: Implementation of CImplActionDelete.
//   $Id$

#include "stdafx.h"
#include "actiondelete.h"
#include "XFormsElementDelete.h"
#include "model.h"
#include "XFormsXFormsElement.h"
#include "ImplBind.h"
CImplActionDelete::CImplActionDelete(CXFormsElementDelete *pXFEl)
	:CImplActionWithOnDemandBindingsAndOutOfLineContext()
{
	m_pXFormsElement = pXFEl;
	pXFEl->AddRef();

}

CImplActionDelete::CImplActionDelete()
{

}

HRESULT CImplActionDelete::PerformAction()
{
	HRESULT hr = E_FAIL;
	ResolveEvaluationContext();
	if(m_pXForms) 
	{
		if(!m_pModel)
			ResolveEvaluationContext();
		if(m_pModel)
		{
			m_pXForms->IncreaseDeferredUpdateCnt();
			m_pXForms->putXPathIdentityResolver(GetIdResolver());
			CComPtr<IXMLDOMNode> pContext;
			GetXPathContext(&pContext);
					//Get the target nodeset
			CImplBind * pBind = 0;
			CComPtr<IXPathResult> pResult;
			if(m_sBind)
			{
				m_pXForms->getBind(m_sBind,pBind);
			}
			else if(m_sNodeset)
			{
				m_pModel->getInstanceNodeList(m_sNodeset,pContext,false,&pResult);
			}
			
			CComPtr<IXMLDOMNode> pNodeToDelete;
			GetNodeToDelete(pBind,pResult,&pNodeToDelete);
			
			if(pNodeToDelete)
			{
				CComPtr<IXMLDOMNode> pParent;
				hr = pNodeToDelete->get_parentNode(&pParent);
				if(pParent)
				{
					CComPtr<IXMLDOMNode> pDeleted;
					hr = pParent->removeChild(pNodeToDelete,&pDeleted);
				}

			}

			if(SUCCEEDED(hr))
			{
				//notify the host and run custom event handlers.
				m_pModel->FireEvent(EVENT_DELETE);

				/*
				* Allow the form to be refreshed
				*/

				hr =  m_pModel->rebuild(m_pXForms->IsInDeferredUpdate());
				if (S_OK == hr)
					hr =  m_pModel->recalculate(m_pXForms->IsInDeferredUpdate());
				if (S_OK == hr)
					hr =  m_pModel->revalidate(m_pXForms->IsInDeferredUpdate());
				if (S_OK == hr)
					hr =  m_pModel->refresh(m_pXForms->IsInDeferredUpdate());
			}
			m_pXForms->putXPathIdentityResolver(0);
			m_pXForms->DecreaseDeferredUpdateCnt();
		}
	}
	return hr;
}


HRESULT CImplActionDelete::GetNodeToDelete(CImplBind * pBind,IXPathResult * pResult, IXMLDOMNode ** ppNodeToDelete)
{
	HRESULT hr = E_FAIL;
	CComPtr<IXMLDOMNode> pContextNode;
	unsigned long max = 0;
	if(pBind)
	{
		max = pBind->GetNodesetLength()-1;
		hr = pBind->GetNodeAt(0,&pContextNode);
	}
	else if(pResult)
	{
		hr = pResult->get_snapshotLength(&max);
		--max;
		if(SUCCEEDED(hr))
			hr = pResult->snapshotItem(0,&pContextNode);
	}

	unsigned long ulAt;
	if(m_sAt)
	{
		hr = m_pModel->getNodesetActionLocation(pContextNode,m_sAt,max,&ulAt);
	}
	else
	{
		ulAt = max;
	}
	
	if(pBind)
		hr = pBind->GetNodeAt(ulAt,ppNodeToDelete);
	else if(pResult)
			hr = pResult->snapshotItem(ulAt,ppNodeToDelete);

	return hr;
}

void CImplActionDelete::ResolveBindings()
{
}

CImplActionDelete::~CImplActionDelete()
{

}